package com.tenclass.common.interceptor.response;

import com.tenclass.common.annotation.Simple;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.io.IOException;
import java.util.List;

import static cn.ilanxin.common.type.v2.ResultKt.ok;


/**
 * 响应包装处理
 * @author YIJIUE
 * @since 1.1.0
 */
public class WrapperResponseHandler extends RequestResponseBodyMethodProcessor implements HandlerMethodReturnValueHandler {

    public WrapperResponseHandler(List<HttpMessageConverter<?>> converters) {
        super(converters);
    }

    @Override
    public boolean supportsReturnType(MethodParameter methodParameter) {
        return (AnnotatedElementUtils.hasAnnotation(methodParameter.getContainingClass(), ResponseBody.class) ||
                methodParameter.hasMethodAnnotation(ResponseBody.class)) && !AnnotatedElementUtils.hasAnnotation(methodParameter.getContainingClass(), Simple.class)
                && !methodParameter.hasMethodAnnotation(Simple.class);
    }

    @Override
    public void handleReturnValue(Object o, @NonNull MethodParameter methodParameter, @NonNull ModelAndViewContainer modelAndViewContainer, @NonNull NativeWebRequest nativeWebRequest) throws IOException, HttpMediaTypeNotAcceptableException {
        modelAndViewContainer.setRequestHandled(true);
        ServletServerHttpRequest inputMessage = createInputMessage(nativeWebRequest);
        ServletServerHttpResponse outputMessage = createOutputMessage(nativeWebRequest);
        outputMessage.getHeaders().add("Encode-f", "-1");
        writeWithMessageConverters(ok(o), methodParameter, inputMessage, outputMessage);
    }
}
